home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / xlib / tprim_pup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  17.4 KB  |  771 lines

  1. /*
  2.  * Copyright 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <GL/glx.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <unistd.h>
  21. #include <stdlib.h>
  22. #include <X11/keysym.h>
  23.  
  24. #include "pup.h"
  25.  
  26. static int RGB_attributes[] = {
  27.     GLX_RGBA,
  28.     GLX_RED_SIZE, 1,
  29.     GLX_GREEN_SIZE, 1,
  30.     GLX_BLUE_SIZE, 1,
  31.     None,
  32. };
  33.  
  34. static int CI_attributes[] = {
  35.     None,
  36. };
  37.  
  38. int rgb = 1;
  39.  
  40. #define PIXEL_CENTER(x) ((long) (x) + 0.5)
  41. #define SETCOLOR(x) (rgb ? glColor3fv(rgbMap[x]) : glIndexf(x))
  42.  
  43. enum {
  44.     BLACK = 0,
  45.     RED,
  46.     GREEN,
  47.     YELLOW,
  48.     BLUE,
  49.     MAGENTA,
  50.     CYAN,
  51.     WHITE
  52. };
  53.  
  54. static float rgbMap[8][3] = {
  55.     {0, 0, 0},
  56.     {1, 0, 0},
  57.     {0, 1, 0},
  58.     {1, 1, 0},
  59.     {0, 0, 1},
  60.     {1, 0, 1},
  61.     {0, 1, 1},
  62.     {1, 1, 1}
  63. };
  64.  
  65.  
  66. #define GAP 10
  67. #define ROWS 3
  68. #define COLS 4
  69.  
  70. static long W = COLS*100 + (COLS + 1)*GAP;
  71. static long H = ROWS*100 + (ROWS + 1)*GAP;
  72. static long boxW = 101;
  73. static long boxH = 101;
  74.  
  75. static void Viewport(long row, long column)
  76. {
  77.     long x, y;
  78.  
  79.     x = GAP + column * (boxW + GAP);
  80.     y = GAP + row * (boxH + GAP);
  81.  
  82.     if (rgb) {
  83.     glClearColor(0, 0, 0, 0);
  84.     } else {
  85.     glClearIndex(0);
  86.     }
  87.  
  88.     glEnable(GL_SCISSOR_TEST);
  89.     glScissor(x, y, boxW, boxH);
  90.     glViewport(x, y, boxW, boxH);
  91.  
  92.     glPushAttrib(GL_COLOR_BUFFER_BIT);
  93.     glColorMask(1, 1, 1, 1);
  94.     glIndexMask(~0);
  95.     glClear(GL_COLOR_BUFFER_BIT);
  96.     glPopAttrib();
  97.  
  98.     glMatrixMode(GL_PROJECTION);
  99.     glLoadIdentity();
  100.     glOrtho(-boxW/2, boxW/2, -boxH/2, boxH/2, 0.0, 1.0);
  101.     glMatrixMode(GL_MODELVIEW);
  102. }
  103.  
  104. static void Point(void)
  105. {
  106.     long i;
  107.  
  108.     SETCOLOR(WHITE);
  109.     glBegin(GL_POINTS);
  110.     glVertex2i(0, 0);
  111.     for (i = 1; i < 8; i++) {
  112.         long j = i * 2;
  113.         SETCOLOR(i);
  114.         glVertex2i(-j, -j);
  115.         glVertex2i(-j, 0);
  116.         glVertex2i(-j, j);
  117.         glVertex2i(0, j);
  118.         glVertex2i(j, j);
  119.         glVertex2i(j, 0);
  120.         glVertex2i(j, -j);
  121.         glVertex2i(0, -j);
  122.     }
  123.     glEnd();
  124. }
  125.  
  126. static void Lines(void)
  127. {
  128.     long i;
  129.  
  130.     glPushMatrix();
  131.     glTranslatef(-12, 0, 0);
  132.     for (i = 1; i < 8; i++) {
  133.     SETCOLOR(i);
  134.     glBegin(GL_LINES);
  135.         glVertex2i(-boxW/4, -boxH/4);
  136.         glVertex2i(boxW/4, boxH/4);
  137.     glEnd();
  138.     glTranslatef(4, 0, 0);
  139.     }
  140.     glPopMatrix();
  141.  
  142.     /*
  143.     ** Draw a single vertex line to make sure nothing bad happens
  144.     */
  145.     glBegin(GL_LINES);
  146.     glVertex2i(0, 0);
  147.     glEnd();
  148. }
  149.  
  150. static void LineStrip(void)
  151. {
  152.     glBegin(GL_LINE_STRIP);
  153.     SETCOLOR(RED);
  154.     glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(-boxH/4));
  155.     SETCOLOR(GREEN);
  156.     glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(boxH/4));
  157.     SETCOLOR(BLUE);
  158.     glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(boxH/4));
  159.     SETCOLOR(WHITE);
  160.     glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(-boxH/4));
  161.     glEnd();
  162.  
  163.     /*
  164.     ** Draw a single vertex line to make sure nothing bad happens
  165.     */
  166.     glBegin(GL_LINE_STRIP);
  167.     glVertex2i(0, 0);
  168.     glEnd();
  169. }
  170.  
  171. static void LineLoop(void)
  172. {
  173.     glBegin(GL_LINE_LOOP);
  174.     SETCOLOR(RED);
  175.     glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(-boxH/4));
  176.     SETCOLOR(GREEN);
  177.     glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(boxH/4));
  178.     SETCOLOR(BLUE);
  179.     glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(boxH/4));
  180.     SETCOLOR(WHITE);
  181.     glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(-boxH/4));
  182.     glEnd();
  183.  
  184.     /*
  185.     ** Draw a two vertex line with XOR on to make sure that only the
  186.     ** endpoints show.  Since each line segment is drawn half-open,
  187.     ** the endpoints will not be drawn twice, thus leaving the XOR of
  188.     ** white in the color buffer.  When using an RGB color buffer, use
  189.     ** the blend function to approximate the effects of the XOR.
  190.     */
  191.     glEnable(GL_LOGIC_OP);
  192.     glEnable(GL_BLEND);
  193.     glLogicOp(GL_XOR);
  194.     glBlendFunc(GL_ONE, GL_ONE);
  195.     SETCOLOR(MAGENTA);
  196.     /* this line is vertical */
  197.     glBegin(GL_LINE_LOOP);
  198.     glVertex2f(PIXEL_CENTER(-boxW/8), PIXEL_CENTER(-boxH/8));
  199.     glVertex2f(PIXEL_CENTER(-boxW/8), PIXEL_CENTER(boxH/8));
  200.     glEnd();
  201.     /* this line is horizontal */
  202.     glBegin(GL_LINE_LOOP);
  203.     glVertex2f(PIXEL_CENTER(-boxW/8), PIXEL_CENTER(boxH/8+5));
  204.     glVertex2f(PIXEL_CENTER(boxW/8), PIXEL_CENTER(boxH/8+5));
  205.     glEnd();
  206.     glDisable(GL_LOGIC_OP);
  207.     glDisable(GL_BLEND);
  208.  
  209.     /*
  210.     ** Draw a point at the center of the area so that we can count pixels
  211.     ** if needed.
  212.     */
  213.     SETCOLOR(GREEN);
  214.     glBegin(GL_POINTS);
  215.     glVertex2i(0, 0);
  216.     glEnd();
  217.  
  218.     /*
  219.     ** Draw a single vertex line to make sure nothing bad happens
  220.     */
  221.     glBegin(GL_LINE_LOOP);
  222.     glVertex2i(0, 0);
  223.     glEnd();
  224. }
  225.  
  226. #define OPENGL_WIDTH    48
  227. #define OPENGL_HEIGHT    13
  228. static GLubyte OpenGL_bits[] = {
  229.    0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
  230.    0x7f, 0xfb, 0xff, 0xff, 0xff, 0x01,
  231.    0x7f, 0xfb, 0xff, 0xff, 0xff, 0x01, 
  232.    0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
  233.    0x3e, 0x8f, 0xb7, 0xf9, 0xfc, 0x01, 
  234.    0x63, 0xdb, 0xb0, 0x8d, 0x0d, 0x00,
  235.    0x63, 0xdb, 0xb7, 0x8d, 0x0d, 0x00, 
  236.    0x63, 0xdb, 0xb6, 0x8d, 0x0d, 0x00,
  237.    0x63, 0x8f, 0xf3, 0xcc, 0x0d, 0x00, 
  238.    0x63, 0x00, 0x00, 0x0c, 0x4c, 0x0a,
  239.    0x63, 0x00, 0x00, 0x0c, 0x4c, 0x0e, 
  240.    0x63, 0x00, 0x00, 0x8c, 0xed, 0x0e,
  241.    0x3e, 0x00, 0x00, 0xf8, 0x0c, 0x00, 
  242. };
  243.  
  244. static void Bitmap(void)
  245. {
  246.     static const long xOrigin = 0;
  247.     static const long yOrigin = 3;
  248.  
  249.     /*
  250.     ** Draw some lines showing the left and bottom edges of the bitmap.
  251.     ** The red line is the vertical left edge of the bitmap.  The blue
  252.     ** line is the horizontal bottom edge of the bitmap.  The yellow line
  253.     ** is the horizontal base line of the bitmap.  The green lines mark
  254.     ** where the rasterpos will translate to. Take into account the x
  255.     ** origin.
  256.     */
  257.     glBegin(GL_LINES);
  258.     SETCOLOR(GREEN);
  259.     glVertex2i(-boxW/2, 0);
  260.     glVertex2i(boxW/2, 0);
  261.     glVertex2i(0, -boxH/2);
  262.     glVertex2i(0, boxH/2);
  263.     SETCOLOR(RED);
  264.     glVertex2i(-xOrigin, -yOrigin);
  265.     glVertex2i(-xOrigin, -yOrigin+OPENGL_HEIGHT);
  266.     SETCOLOR(BLUE);
  267.     glVertex2i(-xOrigin, -yOrigin);
  268.     glVertex2i(-xOrigin+OPENGL_WIDTH, -yOrigin);
  269.     glEnd();
  270.  
  271.     SETCOLOR(GREEN);
  272.  
  273.     glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
  274.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  275.  
  276.     glRasterPos2i(0, 0);
  277.     glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, xOrigin, yOrigin, 0.0, 0.0, 
  278.         OpenGL_bits);
  279. }
  280.  
  281. static void Triangles(void)
  282. {
  283.     glBegin(GL_TRIANGLES);
  284.     SETCOLOR(GREEN);
  285.     glVertex2i(-boxW/4, -boxH/4);
  286.     SETCOLOR(RED);
  287.     glVertex2i(-boxW/8, -boxH/16);
  288.     SETCOLOR(BLUE);
  289.     glVertex2i(boxW/8, -boxH/16);
  290.  
  291.     SETCOLOR(GREEN);
  292.     glVertex2i(-boxW/4, boxH/4);
  293.     SETCOLOR(RED);
  294.     glVertex2i(-boxW/8, boxH/16);
  295.     SETCOLOR(BLUE);
  296.     glVertex2i(boxW/8, boxH/16);
  297.     glEnd();
  298.  
  299.     /*
  300.     ** Generate a 2 vertex triangle that should draw nothing
  301.     */
  302.     glBegin(GL_TRIANGLES);
  303.     glVertex2i(0, 0);
  304.     glVertex2i(-100, 100);
  305.     glEnd();
  306. }
  307.  
  308. static void TriangleStrip(void)
  309. {
  310.     glBegin(GL_TRIANGLE_STRIP);
  311.     SETCOLOR(GREEN);
  312.     glVertex2i(-boxW/4, -boxH/4);
  313.     SETCOLOR(RED);
  314.     glVertex2i(-boxW/4, boxH/4);
  315.     SETCOLOR(BLUE);
  316.     glVertex2i(0, -boxH/4);
  317.     SETCOLOR(WHITE);
  318.     glVertex2i(0, boxH/4);
  319.     SETCOLOR(CYAN);
  320.     glVertex2i(boxW/4, -boxH/4);
  321.     SETCOLOR(YELLOW);
  322.     glVertex2i(boxW/4, boxH/4);
  323.     glEnd();
  324.  
  325.     /*
  326.     ** Generate a 2 vertex triangle strip that should draw nothing
  327.     */
  328.     glBegin(GL_TRIANGLE_STRIP);
  329.     glVertex2i(0, 0);
  330.     glVertex2i(-100, 100);
  331.     glEnd();
  332. }
  333.  
  334. static void TriangleFan(void)
  335. {
  336.     long x0, x1, x2, x3;
  337.     long y0, y1, y2, y3;
  338.     long vx[8][2];
  339.     long i;
  340.  
  341.     /*
  342.     ** Construct an 8 sided convex polygon that is almost an octahedron
  343.     */
  344.     y0 = -boxH/4;
  345.     y1 = y0 + boxH/2/3;
  346.     y2 = y1 + boxH/2/3;
  347.     y3 = boxH/4;
  348.     x0 = -boxW/4;
  349.     x1 = x0 + boxW/2/3;
  350.     x2 = x1 + boxW/2/3;
  351.     x3 = boxW/4;
  352.  
  353.     vx[0][0] = x0; vx[0][1] = y1;
  354.     vx[1][0] = x0; vx[1][1] = y2;
  355.     vx[2][0] = x1; vx[2][1] = y3;
  356.     vx[3][0] = x2; vx[3][1] = y3;
  357.     vx[4][0] = x3; vx[4][1] = y2;
  358.     vx[5][0] = x3; vx[5][1] = y1;
  359.     vx[6][0] = x2; vx[6][1] = y0;
  360.     vx[7][0] = x1; vx[7][1] = y0;
  361.  
  362.     /*
  363.     ** Draw the polygon, shaded.  This will draw the same shape that the
  364.     ** polygon test draws, except that when flat shaded it should draw
  365.     ** entirely white.  When smooth shaded it will shade differently
  366.     ** than the polygon test.
  367.     */
  368.     glBegin(GL_TRIANGLE_FAN);
  369.     SETCOLOR(WHITE);
  370.     glVertex2i(0, 0);
  371.     for (i = 0; i < 8; i++) {
  372.         SETCOLOR(7-i);
  373.         glVertex2iv((const GLint *)vx[i]);
  374.     }
  375.     glEnd();
  376.  
  377.     /*
  378.     ** Generate a 2 vertex triangle fan that should draw nothing
  379.     */
  380.     glBegin(GL_TRIANGLE_FAN);
  381.     glVertex2i(0, 0);
  382.     glVertex2i(-100, 100);
  383.     glEnd();
  384. }
  385.  
  386. static void Rect(void)
  387. {
  388.     SETCOLOR(GREEN);
  389.     glRecti(-boxW/4, -boxH/4, boxW/4, boxH/4);
  390. }
  391.  
  392. static void Polygon(void)
  393. {
  394.     long x0, x1, x2, x3;
  395.     long y0, y1, y2, y3;
  396.     long vx[8][2];
  397.     long i;
  398.  
  399.     /*
  400.     ** Construct an 8 sided convex polygon that is almost an octahedron
  401.     */
  402.     y0 = -boxH/4;
  403.     y1 = y0 + boxH/2/3;
  404.     y2 = y1 + boxH/2/3;
  405.     y3 = boxH/4;
  406.     x0 = -boxW/4;
  407.     x1 = x0 + boxW/2/3;
  408.     x2 = x1 + boxW/2/3;
  409.     x3 = boxW/4;
  410.  
  411.     vx[0][0] = x0; vx[0][1] = y1;
  412.     vx[1][0] = x0; vx[1][1] = y2;
  413.     vx[2][0] = x1; vx[2][1] = y3;
  414.     vx[3][0] = x2; vx[3][1] = y3;
  415.     vx[4][0] = x3; vx[4][1] = y2;
  416.     vx[5][0] = x3; vx[5][1] = y1;
  417.     vx[6][0] = x2; vx[6][1] = y0;
  418.     vx[7][0] = x1; vx[7][1] = y0;
  419.  
  420.     /*
  421.     ** Draw the polygon, shaded.
  422.     */
  423.     glBegin(GL_POLYGON);
  424.     for (i = 0; i < 8; i++) {
  425.         SETCOLOR(7-i);
  426.         glVertex2iv((const GLint *)vx[i]);
  427.     }
  428.     glEnd();
  429.  
  430.     /*
  431.     ** Generate a 2 vertex polygon that should draw nothing
  432.     */
  433.     glBegin(GL_POLYGON);
  434.     glVertex2i(0, 0);
  435.     glVertex2i(100, 100);
  436.     glEnd();
  437. }
  438.  
  439. static void Quads(void)
  440. {
  441.     glBegin(GL_QUADS);
  442.     SETCOLOR(GREEN);
  443.     glVertex2i(-boxW/4, -boxH/4);
  444.     SETCOLOR(RED);
  445.     glVertex2i(-boxW/8, -boxH/16);
  446.     SETCOLOR(BLUE);
  447.     glVertex2i(boxW/8, -boxH/16);
  448.     SETCOLOR(WHITE);
  449.     glVertex2i(boxW/4, -boxH/4);
  450.  
  451.     SETCOLOR(GREEN);
  452.     glVertex2i(-boxW/4, boxH/4);
  453.     SETCOLOR(RED);
  454.     glVertex2i(-boxW/8, boxH/16);
  455.     SETCOLOR(BLUE);
  456.     glVertex2i(boxW/8, boxH/16);
  457.     SETCOLOR(WHITE);
  458.     glVertex2i(boxW/4, boxH/4);
  459.     glEnd();
  460.  
  461.     /*
  462.     ** Generate a 3 vertex quad that should draw nothing
  463.     */
  464.     glBegin(GL_QUADS);
  465.     glVertex2i(0, 0);
  466.     glVertex2i(100, 100);
  467.     glVertex2i(-100, 100);
  468.     glEnd();
  469. }
  470.  
  471. static void QuadStrip(void)
  472. {
  473.     glBegin(GL_QUAD_STRIP);
  474.     SETCOLOR(GREEN);
  475.     glVertex2i(-boxW/4, -boxH/4);
  476.     SETCOLOR(RED);
  477.     glVertex2i(-boxW/4, boxH/4);
  478.     SETCOLOR(BLUE);
  479.     glVertex2i(0, -boxH/4);
  480.     SETCOLOR(WHITE);
  481.     glVertex2i(0, boxH/4);
  482.     SETCOLOR(CYAN);
  483.     glVertex2i(boxW/4, -boxH/4);
  484.     SETCOLOR(YELLOW);
  485.     glVertex2i(boxW/4, boxH/4);
  486.     glEnd();
  487.  
  488.     /*
  489.     ** Generate a 3 vertex quad strip that should draw nothing
  490.     */
  491.     glBegin(GL_QUAD_STRIP);
  492.     glVertex2i(0, 0);
  493.     glVertex2i(100, 100);
  494.     glVertex2i(-100, 100);
  495.     glEnd();
  496. }
  497.  
  498. static void RotateColorMask(void)
  499. {
  500.     static long rotation=0;
  501.     
  502.     rotation = (rotation + 1) & 0x3;
  503.     switch (rotation) {
  504.       case 0:
  505.     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  506.     glIndexMask( 0xff );
  507.     break;
  508.       case 1:
  509.     /* mask off red */
  510.     glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
  511.     glIndexMask( 0xfe );
  512.     break;
  513.       case 2:
  514.     /* mask off green */
  515.     glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
  516.     glIndexMask( 0xfd );
  517.     break;
  518.       case 3:
  519.     /* mask off blue */
  520.     glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
  521.     glIndexMask( 0xfb );
  522.     break;
  523.     }
  524. }
  525.  
  526. static void DoTests(void)
  527. {
  528.     glClearColor(0.0, 0.0, 0.0, 0.0);
  529.  
  530.     Viewport(0, 0); Point();
  531.     Viewport(0, 1); Lines();
  532.     Viewport(0, 2); LineStrip();
  533.     Viewport(0, 3); LineLoop();
  534.  
  535.     Viewport(1, 0); Bitmap();
  536.     Viewport(1, 1); TriangleFan();
  537.     Viewport(1, 2); Triangles();
  538.     Viewport(1, 3); TriangleStrip();
  539.  
  540.     Viewport(2, 0); Rect();
  541.     Viewport(2, 1); Polygon();
  542.     Viewport(2, 2); Quads();
  543.     Viewport(2, 3); QuadStrip();
  544.  
  545.     glFlush();
  546. }
  547.  
  548. static void Usage(void)
  549. {
  550.     printf("Usage: tprim [-c]\n");
  551.     printf("   -c:  Run in color index mode\n");
  552.     exit(-1);
  553. }
  554.  
  555. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  556. {
  557.     if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
  558.     return GL_TRUE;
  559.     }
  560.     return GL_FALSE;
  561. }
  562.  
  563. int main(int argc, char** argv)
  564. {
  565.     XVisualInfo *vi;
  566.     Display *dpy;
  567.     Colormap cmap;
  568.     Window window;
  569.     XSetWindowAttributes swa;
  570.     GLXContext cx;
  571.     XEvent event;
  572.     GLboolean needDisplay;
  573.     XColor white;
  574.     char *geometry = NULL;
  575.     XSizeHints sizehints;
  576.     int i;
  577.     long menu, smenu, pmenu;
  578.  
  579.     rgb = 1;
  580.     for (i = 1; i < argc; i++) {
  581.     if (!strcmp(argv[i], "-geometry")) {
  582.         i++;
  583.         geometry = argv[i];
  584.     } else if (argv[i][0] == '-') {
  585.             switch (argv[i][1]) {
  586.               case 'c':
  587.                 rgb = GL_FALSE;
  588.                 break;
  589.               default:
  590.                 Usage();
  591.             }
  592.         } else {
  593.             Usage();
  594.         }
  595.     }
  596.  
  597.     dpy = XOpenDisplay(0);
  598.     if (!dpy) {
  599.     fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
  600.     return -1;
  601.     }
  602.  
  603.     vi = glXChooseVisual(dpy, DefaultScreen(dpy),
  604.              rgb ? RGB_attributes : CI_attributes);
  605.     if (!vi) {
  606.     fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
  607.         getenv("DISPLAY"));
  608.     return -1;
  609.     }
  610.  
  611.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  612.                AllocNone);
  613.     white.red = ~0;
  614.     white.green = ~0;
  615.     white.blue = ~0;
  616.     XAllocColor(dpy, cmap, &white);
  617.  
  618.     sizehints.flags = PPosition | PSize;
  619.     sizehints.width = W;
  620.     sizehints.height = H;
  621.     sizehints.x = 10;
  622.     sizehints.y = 10;
  623.     if(geometry) {
  624.     int flags, x, y, width, height;
  625.  
  626.     flags = XParseGeometry(geometry, &x, &y,
  627.                    (unsigned int *)&width,
  628.                    (unsigned int *)&height);
  629.         if(WidthValue & flags) {
  630.         sizehints.flags |= USSize;
  631.         sizehints.width = width;
  632.         W = width;
  633.     }
  634.     if(HeightValue & flags) {
  635.         sizehints.flags |= USSize;
  636.         sizehints.height = height;
  637.         H = height;
  638.     }
  639.     if(XValue & flags) {
  640.         if(XNegative & flags)
  641.         x = DisplayWidth(dpy, DefaultScreen(dpy)) + x 
  642.             - sizehints.width;
  643.             sizehints.flags |= USPosition;
  644.         sizehints.x = x;
  645.     }
  646.     if(YValue & flags) {
  647.         if(YNegative & flags)
  648.         y = DisplayHeight(dpy, DefaultScreen(dpy)) + y 
  649.             - sizehints.height;
  650.             sizehints.flags |= USPosition;
  651.         sizehints.y = y;
  652.     }
  653.     }
  654.     swa.border_pixel = 0;
  655.     swa.background_pixel = white.pixel;
  656.     swa.colormap = cmap;
  657.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
  658.     | KeyReleaseMask | ButtonPressMask;
  659.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
  660.                            sizehints.x, sizehints.y,
  661.                sizehints.width, sizehints.height,
  662.                0, vi->depth, InputOutput, vi->visual,
  663.                CWBackPixel|CWBorderPixel|CWColormap|CWEventMask,
  664.                &swa);
  665.     XSetStandardProperties(dpy, window, rgb ? "tprim RGB" : "tprim CI", "tprim",
  666.                            None, argv, argc, &sizehints);
  667.     XSetWMColormapWindows(dpy, window, &window, 1);
  668.     XMapWindow(dpy, window);
  669.     XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
  670.  
  671.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
  672.     if (!glXMakeCurrent(dpy, window, cx)) {
  673.     fprintf(stderr, "Can't make window current to context\n");
  674.     return -1;
  675.     }
  676.     smenu = defpup(dpy, DefaultScreen(dpy), "GL_FLAT %x1|GL_SMOOTH %x2");
  677.     pmenu = defpup(dpy, DefaultScreen(dpy), "GL_FILL %x3|GL_LINE %x4|GL_POINT %x5");
  678.     menu = defpup(dpy, DefaultScreen(dpy), "glShadeModel %m|glPolygonMode %m|rotate color mask %x6%l|quit %x7", smenu, pmenu);
  679.  
  680.     needDisplay = GL_TRUE;
  681.     for (;;) {
  682.     do {
  683.         XNextEvent(dpy, &event);
  684.         switch (event.type) {
  685.           case Expose:
  686.         needDisplay = GL_TRUE;
  687.         break;
  688.           case ConfigureNotify:
  689.         W = event.xconfigure.width;
  690.         H = event.xconfigure.height;
  691.         needDisplay = GL_TRUE;
  692.         break;
  693.           case KeyPress:
  694.         {
  695.             char buf[100];
  696.             int rv;
  697.             KeySym ks;
  698.  
  699.             rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
  700.             switch (ks) {
  701.               case XK_F:
  702.               case XK_f:
  703.             glShadeModel(GL_FLAT);
  704.             needDisplay = GL_TRUE;
  705.             break;
  706.               case XK_S:
  707.               case XK_s:
  708.             glShadeModel(GL_SMOOTH);
  709.             needDisplay = GL_TRUE;
  710.             break;
  711.               case XK_P:
  712.               case XK_p:
  713.             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  714.             needDisplay = GL_TRUE;
  715.             break;
  716.               case XK_L:
  717.               case XK_l:
  718.             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  719.             needDisplay = GL_TRUE;
  720.             break;
  721.               case XK_C:
  722.               case XK_c:
  723.             RotateColorMask();
  724.             needDisplay = GL_TRUE;
  725.             break;
  726.               case XK_Escape:
  727.             return 0;
  728.             }
  729.         }
  730.         break;
  731.           case ButtonPress:
  732.         switch(dopup(menu)) {
  733.         case 1:
  734.             glShadeModel(GL_FLAT);
  735.             needDisplay = GL_TRUE;
  736.             break;
  737.         case 2:
  738.             glShadeModel(GL_SMOOTH);
  739.             needDisplay = GL_TRUE;
  740.             break;
  741.         case 3:
  742.             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  743.             needDisplay = GL_TRUE;
  744.             break;
  745.         case 4:
  746.             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  747.             needDisplay = GL_TRUE;
  748.             break;
  749.         case 5:
  750.             glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
  751.             needDisplay = GL_TRUE;
  752.             break;
  753.         case 6:
  754.             RotateColorMask();
  755.             needDisplay = GL_TRUE;
  756.             break;
  757.         case 7:
  758.             exit(0);
  759.         case -1:
  760.             break;
  761.         }
  762.         }
  763.     } while (XPending(dpy) != 0);
  764.  
  765.     if (needDisplay) {
  766.         needDisplay = GL_FALSE;
  767.         DoTests();
  768.     }
  769.     }
  770. }
  771.